package com.sk.bilibili.apiMapper.component;

import com.sk.bilibili.apiMapper.bean.ClassHolder;

import javax.swing.tree.TreePath;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @author 邵康
 * @date 2021/7/11 18:51
 */
public class ClassBuilder {

    private TreePath[] paths;
    private List<ClassHolder> classHolders;

    public ClassBuilder(TreePath[] paths) {
        this.paths=paths;
        classHolders=new ArrayList<>();
    }

    public String build() {
        initClassHolder();
        StringBuilder builder=new StringBuilder();
        for (ClassHolder classHolder:classHolders){
            buildClass(builder,classHolder);
        }
//        System.out.println(builder);
        return builder.toString();
    }

    private void buildClass(StringBuilder builder, ClassHolder classHolder) {
        buildStart(builder,classHolder.getName());
        buildField(builder,classHolder.getFields());
        buildArray(builder,classHolder.getArray());
        buildEnd(builder);
    }

    private void buildEnd(StringBuilder builder) {
        builder.append("\n}\n");
    }

    private void buildArray(StringBuilder builder, Map<String, ClassHolder> array) {
        for (String key:array.keySet()){
            String name = array.get(key).getName();
            builder.append("\t@FieldPath(collection = true,value=\"").append(key.substring(1))
            .append("\")\n\tprivate ").append(upperCaseFirst(name)).append("[] ").append(name).append(";\n");
        }
    }

    private void buildField(StringBuilder builder, List<String> fields) {
        for (String field:fields){
            builder.append("\t@FieldPath(\"").append(field).append("\")\n\tprivate String ")
                    .append(getName(field)).append(";\n");
        }
    }

    private String getName(String field) {
        int index = field.lastIndexOf('.');
        if(index==-1)return field;
        return field.substring(index+1);
    }

    private void buildStart(StringBuilder builder, String name) {
        builder.append("@Data\npublic class ").append(upperCaseFirst(name)).append(" {\n\n");
    }

    private char[] upperCaseFirst(String name) {
        char[] array = name.toCharArray();
        array[0]&='_';
        return array;
    }

    private void initClassHolder() {
        ClassHolder classHolder = new ClassHolder("ROOT");
        classHolders.add(classHolder);
        StringBuilder builder=new StringBuilder();
        for (TreePath path : paths) {
            builder.setLength(0);
            next(classHolder,path,builder,1);
        }
    }

    private void next(ClassHolder classHolder, TreePath path, StringBuilder builder, int index) {
        if(index<path.getPathCount()){
            String name = path.getPathComponent(index).toString();
            if(name.startsWith("$")){
                name=name.substring(1);
                builder.append('.').append(name);
                classHolder=classHolder.getClassHolder(builder.toString(),name,classHolders);
                builder.setLength(0);
            }else {
                builder.append('.').append(name);
            }
            next(classHolder,path,builder,index+1);
        }else {
            classHolder.addField(builder.substring(1));
        }
    }

}
